home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / WarpQuake / Src / cd_linux.c < prev    next >
C/C++ Source or Header  |  2000-05-22  |  8KB  |  417 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All
  21. // rights reserved.
  22.  
  23. #include <stdio.h>
  24. #include <unistd.h>
  25. #include <stdlib.h>
  26. #include <sys/ioctl.h>
  27. #include <sys/file.h>
  28. #include <sys/types.h>
  29. #include <fcntl.h>
  30. #include <string.h>
  31. #include <time.h>
  32. #include <errno.h>
  33.  
  34. #include <linux/cdrom.h>
  35.  
  36. #include "quakedef.h"
  37.  
  38. static qboolean cdValid = false;
  39. static qboolean    playing = false;
  40. static qboolean    wasPlaying = false;
  41. static qboolean    initialized = false;
  42. static qboolean    enabled = true;
  43. static qboolean playLooping = false;
  44. static float    cdvolume;
  45. static byte     remap[100];
  46. static byte        playTrack;
  47. static byte        maxTrack;
  48.  
  49. static int cdfile = -1;
  50. static char cd_dev[64] = "/dev/cdrom";
  51.  
  52. static void CDAudio_Eject(void)
  53. {
  54.     if (cdfile == -1 || !enabled)
  55.         return; // no cd init'd
  56.  
  57.     if ( ioctl(cdfile, CDROMEJECT) == -1 ) 
  58.         Con_DPrintf("ioctl cdromeject failed\n");
  59. }
  60.  
  61.  
  62. static void CDAudio_CloseDoor(void)
  63. {
  64.     if (cdfile == -1 || !enabled)
  65.         return; // no cd init'd
  66.  
  67.     if ( ioctl(cdfile, CDROMCLOSETRAY) == -1 ) 
  68.         Con_DPrintf("ioctl cdromclosetray failed\n");
  69. }
  70.  
  71. static int CDAudio_GetAudioDiskInfo(void)
  72. {
  73.     struct cdrom_tochdr tochdr;
  74.  
  75.     cdValid = false;
  76.  
  77.     if ( ioctl(cdfile, CDROMREADTOCHDR, &tochdr) == -1 ) 
  78.     {
  79.       Con_DPrintf("ioctl cdromreadtochdr failed\n");
  80.       return -1;
  81.     }
  82.  
  83.     if (tochdr.cdth_trk0 < 1)
  84.     {
  85.         Con_DPrintf("CDAudio: no music tracks\n");
  86.         return -1;
  87.     }
  88.  
  89.     cdValid = true;
  90.     maxTrack = tochdr.cdth_trk1;
  91.  
  92.     return 0;
  93. }
  94.  
  95.  
  96. void CDAudio_Play(byte track, qboolean looping)
  97. {
  98.     struct cdrom_tocentry entry;
  99.     struct cdrom_ti ti;
  100.  
  101.     if (cdfile == -1 || !enabled)
  102.         return;
  103.     
  104.     if (!cdValid)
  105.     {
  106.         CDAudio_GetAudioDiskInfo();
  107.         if (!cdValid)
  108.             return;
  109.     }
  110.  
  111.     track = remap[track];
  112.  
  113.     if (track < 1 || track > maxTrack)
  114.     {
  115.         Con_DPrintf("CDAudio: Bad track number %u.\n", track);
  116.         return;
  117.     }
  118.  
  119.     // don't try to play a non-audio track
  120.     entry.cdte_track = track;
  121.     entry.cdte_format = CDROM_MSF;
  122.     if ( ioctl(cdfile, CDROMREADTOCENTRY, &entry) == -1 )
  123.     {
  124.         Con_DPrintf("ioctl cdromreadtocentry failed\n");
  125.         return;
  126.     }
  127.     if (entry.cdte_ctrl == CDROM_DATA_TRACK)
  128.     {
  129.         Con_Printf("CDAudio: track %i is not audio\n", track);
  130.         return;
  131.     }
  132.  
  133.     if (playing)
  134.     {
  135.         if (playTrack == track)
  136.             return;
  137.         CDAudio_Stop();
  138.     }
  139.  
  140.     ti.cdti_trk0 = track;
  141.     ti.cdti_trk1 = track;
  142.     ti.cdti_ind0 = 1;
  143.     ti.cdti_ind1 = 99;
  144.  
  145.     if ( ioctl(cdfile, CDROMPLAYTRKIND, &ti) == -1 ) 
  146.     {
  147.         Con_DPrintf("ioctl cdromplaytrkind failed\n");
  148.         return;
  149.     }
  150.  
  151.     if ( ioctl(cdfile, CDROMRESUME) == -1 ) 
  152.         Con_DPrintf("ioctl cdromresume failed\n");
  153.  
  154.     playLooping = looping;
  155.     playTrack = track;
  156.     playing = true;
  157.  
  158.     if (cdvolume == 0.0)
  159.         CDAudio_Pause ();
  160. }
  161.  
  162.  
  163. void CDAudio_Stop(void)
  164. {
  165.     if (cdfile == -1 || !enabled)
  166.         return;
  167.     
  168.     if (!playing)
  169.         return;
  170.  
  171.     if ( ioctl(cdfile, CDROMSTOP) == -1 )
  172.         Con_DPrintf("ioctl cdromstop failed (%d)\n", errno);
  173.  
  174.     wasPlaying = false;
  175.     playing = false;
  176. }
  177.  
  178. void CDAudio_Pause(void)
  179. {
  180.     if (cdfile == -1 || !enabled)
  181.         return;
  182.  
  183.     if (!playing)
  184.         return;
  185.  
  186.     if ( ioctl(cdfile, CDROMPAUSE) == -1 ) 
  187.         Con_DPrintf("ioctl cdrompause failed\n");
  188.  
  189.     wasPlaying = playing;
  190.     playing = false;
  191. }
  192.  
  193.  
  194. void CDAudio_Resume(void)
  195. {
  196.     if (cdfile == -1 || !enabled)
  197.         return;
  198.     
  199.     if (!cdValid)
  200.         return;
  201.  
  202.     if (!wasPlaying)
  203.         return;
  204.     
  205.     if ( ioctl(cdfile, CDROMRESUME) == -1 ) 
  206.         Con_DPrintf("ioctl cdromresume failed\n");
  207.     playing = true;
  208. }
  209.  
  210. static void CD_f (void)
  211. {
  212.     char    *command;
  213.     int        ret;
  214.     int        n;
  215.  
  216.     if (Cmd_Argc() < 2)
  217.         return;
  218.  
  219.     command = Cmd_Argv (1);
  220.  
  221.     if (Q_strcasecmp(command, "on") == 0)
  222.     {
  223.         enabled = true;
  224.         return;
  225.     }
  226.  
  227.     if (Q_strcasecmp(command, "off") == 0)
  228.     {
  229.         if (playing)
  230.             CDAudio_Stop();
  231.         enabled = false;
  232.         return;
  233.     }
  234.  
  235.     if (Q_strcasecmp(command, "reset") == 0)
  236.     {
  237.         enabled = true;
  238.         if (playing)
  239.             CDAudio_Stop();
  240.         for (n = 0; n < 100; n++)
  241.             remap[n] = n;
  242.         CDAudio_GetAudioDiskInfo();
  243.         return;
  244.     }
  245.  
  246.     if (Q_strcasecmp(command, "remap") == 0)
  247.     {
  248.         ret = Cmd_Argc() - 2;
  249.         if (ret <= 0)
  250.         {
  251.             for (n = 1; n < 100; n++)
  252.                 if (remap[n] != n)
  253.                     Con_Printf("  %u -> %u\n", n, remap[n]);
  254.             return;
  255.         }
  256.         for (n = 1; n <= ret; n++)
  257.             remap[n] = Q_atoi(Cmd_Argv (n+1));
  258.         return;
  259.     }
  260.  
  261.     if (Q_strcasecmp(command, "close") == 0)
  262.     {
  263.         CDAudio_CloseDoor();
  264.         return;
  265.     }
  266.  
  267.     if (!cdValid)
  268.     {
  269.         CDAudio_GetAudioDiskInfo();
  270.         if (!cdValid)
  271.         {
  272.             Con_Printf("No CD in player.\n");
  273.             return;
  274.         }
  275.     }
  276.  
  277.     if (Q_strcasecmp(command, "play") == 0)
  278.     {
  279.         CDAudio_Play((byte)Q_atoi(Cmd_Argv (2)), false);
  280.         return;
  281.     }
  282.  
  283.     if (Q_strcasecmp(command, "loop") == 0)
  284.     {
  285.         CDAudio_Play((byte)Q_atoi(Cmd_Argv (2)), true);
  286.         return;
  287.     }
  288.  
  289.     if (Q_strcasecmp(command, "stop") == 0)
  290.     {
  291.         CDAudio_Stop();
  292.         return;
  293.     }
  294.  
  295.     if (Q_strcasecmp(command, "pause") == 0)
  296.     {
  297.         CDAudio_Pause();
  298.         return;
  299.     }
  300.  
  301.     if (Q_strcasecmp(command, "resume") == 0)
  302.     {
  303.         CDAudio_Resume();
  304.         return;
  305.     }
  306.  
  307.     if (Q_strcasecmp(command, "eject") == 0)
  308.     {
  309.         if (playing)
  310.             CDAudio_Stop();
  311.         CDAudio_Eject();
  312.         cdValid = false;
  313.         return;
  314.     }
  315.  
  316.     if (Q_strcasecmp(command, "info") == 0)
  317.     {
  318.         Con_Printf("%u tracks\n", maxTrack);
  319.         if (playing)
  320.             Con_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack);
  321.         else if (wasPlaying)
  322.             Con_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack);
  323.         Con_Printf("Volume is %f\n", cdvolume);
  324.         return;
  325.     }
  326. }
  327.  
  328. void CDAudio_Update(void)
  329. {
  330.     struct cdrom_subchnl subchnl;
  331.     static time_t lastchk;
  332.  
  333.     if (!enabled)
  334.         return;
  335.  
  336.     if (bgmvolume.value != cdvolume)
  337.     {
  338.         if (cdvolume)
  339.         {
  340.             Cvar_SetValue ("bgmvolume", 0.0);
  341.             cdvolume = bgmvolume.value;
  342.             CDAudio_Pause ();
  343.         }
  344.         else
  345.         {
  346.             Cvar_SetValue ("bgmvolume", 1.0);
  347.             cdvolume = bgmvolume.value;
  348.             CDAudio_Resume ();
  349.         }
  350.     }
  351.  
  352.     if (playing && lastchk < time(NULL)) {
  353.         lastchk = time(NULL) + 2; //two seconds between chks
  354.         subchnl.cdsc_format = CDROM_MSF;
  355.         if (ioctl(cdfile, CDROMSUBCHNL, &subchnl) == -1 ) {
  356.             Con_DPrintf("ioctl cdromsubchnl failed\n");
  357.             playing = false;
  358.             return;
  359.         }
  360.         if (subchnl.cdsc_audiostatus != CDROM_AUDIO_PLAY &&
  361.             subchnl.cdsc_audiostatus != CDROM_AUDIO_PAUSED) {
  362.             playing = false;
  363.             if (playLooping)
  364.                 CDAudio_Play(playTrack, true);
  365.         }
  366.     }
  367. }
  368.  
  369. int CDAudio_Init(void)
  370. {
  371.     int i;
  372.  
  373.     if (cls.state == ca_dedicated)
  374.         return -1;
  375.  
  376.     if (COM_CheckParm("-nocdaudio"))
  377.         return -1;
  378.  
  379.     if ((i = COM_CheckParm("-cddev")) != 0 && i < com_argc - 1) {
  380.         strncpy(cd_dev, com_argv[i + 1], sizeof(cd_dev));
  381.         cd_dev[sizeof(cd_dev) - 1] = 0;
  382.     }
  383.  
  384.     if ((cdfile = open(cd_dev, O_RDONLY)) == -1) {
  385.         Con_Printf("CDAudio_Init: open of \"%s\" failed (%i)\n", cd_dev, errno);
  386.         cdfile = -1;
  387.         return -1;
  388.     }
  389.  
  390.     for (i = 0; i < 100; i++)
  391.         remap[i] = i;
  392.     initialized = true;
  393.     enabled = true;
  394.  
  395.     if (CDAudio_GetAudioDiskInfo())
  396.     {
  397.         Con_Printf("CDAudio_Init: No CD in player.\n");
  398.         cdValid = false;
  399.     }
  400.  
  401.     Cmd_AddCommand ("cd", CD_f);
  402.  
  403.     Con_Printf("CD Audio Initialized\n");
  404.  
  405.     return 0;
  406. }
  407.  
  408.  
  409. void CDAudio_Shutdown(void)
  410. {
  411.     if (!initialized)
  412.         return;
  413.     CDAudio_Stop();
  414.     close(cdfile);
  415.     cdfile = -1;
  416. }
  417.